package main

import (
	"fmt"
	"reflect"
)

func dynamicCal(obj interface{}, methodName string, args []interface{}) []interface{} {
	valueInfo := reflect.ValueOf(obj)
	methodInfo := valueInfo.MethodByName(methodName)
	if !methodInfo.IsValid() {
		panic("No such method: " + methodName)
	}
	argValues := make([]reflect.Value, 0)
	for _, arg := range args {
		argValues = append(argValues, reflect.ValueOf(arg))
	}
	returnValues := methodInfo.Call(argValues)
	returnSlice := make([]interface{}, len(returnValues))

	for i := 0; i < len(returnValues); i++ {
		returnSlice[i] = transferValue(returnValues[i])
	}
	return returnSlice
}

func transferValue(value reflect.Value) interface{} {
	kind := value.Kind()
	switch kind {
	case reflect.Int:
		return value.Int()
	case reflect.Float64:
		return value.Float()
	case reflect.Bool:
		return value.Bool()
	case reflect.String:
		return value.String()
	default:
		return value.Interface()
	}
}

type User10 struct {
	Name string
	Age  int
}

func (u *User10) UpdateNameAndAge(name string, age int) {
	u.Name = name
	u.Age = age
}

func (u *User10) GetUserInfo() string {
	return fmt.Sprintf("%v", *u)
}

func main() {
	u := &User10{
		Name: "A",
		Age:  18,
	}
	result := dynamicCal(u, "GetUserInfo", nil)
	userInfo := result[0].(string)
	fmt.Println(userInfo)

	cal := dynamicCal(u, "UpdateNameAndAge", []interface{}{"B", 20})
	//没有返回数据的方法，返回的切片是空的
	fmt.Println(cal, reflect.TypeOf(cal))
	fmt.Println(u)
}
